#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2025/6/21 7:22
# @Author  : summer
# @Email   : 610658552@qq.com
# @File    : pagination.py
# @Software: PyCharm
# @Desc    :

from django.core.paginator import Paginator, InvalidPage
from rest_framework.exceptions import ValidationError
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response


class EnhancedPagination(PageNumberPagination):
    page_size = 10 # 默认每页记录数
    page_size_query_param = 'page_size' # 每页记录参数名
    max_page_size = 100 # 最大每页记录数
    page_query_param = 'page' # 页面参数

    def get_page_number(self, request, paginator):
        """获取并验证页面参数"""
        page_number = request.query_params.get(self.page_query_param, 1)

        # 验证页面是否为正整数
        try:
            page_number = int(page_number)
            if page_number <= 0:
                raise ValueError
        except (TypeError, ValueError):
            raise ValidationError({self.page_query_param: ["页面必须大于0的整数。"]})

        return page_number

    def get_page_size(self, request):
        """获取并验证每页记录数参数"""
        if self.page_size_query_param:
            try:
                page_size = int(request.query_params.get(self.page_size_query_param))

                if page_size <= 0:
                    raise ValidationError({self.page_size_query_param: ["每页记录数必须是大于0的整数"]})

                if page_size > self.max_page_size:
                    raise ValidationError({self.page_size_query_param: [f"每页记录数不能超过{self.max_page_size}"]})

                return page_size
            except (TypeError, ValueError):
                pass
        return self.page_size

    def paginate_queryset(self, queryset, request, view=None):
        """重写分页方法，出来页面超出范围的情况"""
        page_size = self.get_page_size(request)
        if not page_size:
            return None

        paginator = self.django_paginator_class(queryset, page_size)
        page_number = self.get_page_number(request, paginator)

        try:
            """尝试获取请求的页码"""
            self.page = paginator.page(page_number)
        except InvalidPage as exc:
            """如果页面超出范围，返回空列表而不是错误"""
            self.page = self._empty_page()
            return []

        if paginator.num_pages > 1 and self.template is not None:
            self.display_page_controls = True

        self.request = request
        return list(self.page)

    def _empty_page(self):
        """创建一个空的分页对象"""
        paginator = Paginator([], self.page_size)
        return paginator.page(1)

    def get_paginated_response(self, data):
        """自定义分页的响应格式"""
        return Response({
            'success': True,
            'code': 200,
            'message': '操作成功',
            "count": self.page.paginator.count,
            "total_pages": self.page.paginator.num_pages,
            "current_page": self.page.number,
            "page_size": self.page_size,
            "next": self.get_next_link(),
            "previous": self.get_previous_link(),
            "results": data,
        })



class EnhancedPageNumberPagination(PageNumberPagination):
    """增强版分页类，包含参数验证和统一响应格式"""
    page_size = 10  # 默认每页记录数
    page_size_query_param = 'page_size'  # 每页记录数参数名
    max_page_size = 100  # 最大每页记录数
    page_query_param = 'page'  # 页码参数名

    def get_page_number(self, request, paginator):
        """获取并验证页码参数"""
        page_number = request.query_params.get(self.page_query_param, 1)

        # 验证页码是否为正整数
        try:
            page_number = int(page_number)
            if page_number <= 0:
                raise ValueError
        except (TypeError, ValueError):
            raise ValidationError({
                self.page_query_param: ['页码必须是大于0的整数。']
            })

        return page_number

    def get_page_size(self, request):
        """获取并验证每页记录数参数"""
        if self.page_size_query_param:
            try:
                page_size = int(request.query_params[self.page_size_query_param])

                # 验证每页记录数是否为正整数且不超过最大值
                if page_size <= 0:
                    raise ValidationError({
                        self.page_size_query_param: ['每页记录数必须是大于0的整数。']
                    })
                if page_size > self.max_page_size:
                    raise ValidationError({
                        self.page_size_query_param: [f'每页记录数不能超过{self.max_page_size}。']
                    })
                return page_size
            except (KeyError, ValueError):
                pass

        return self.page_size

    def paginate_queryset(self, queryset, request, view=None):
        """重写分页方法，处理页码超出范围的情况"""
        page_size = self.get_page_size(request)
        if not page_size:
            return None

        paginator = self.django_paginator_class(queryset, page_size)
        page_number = self.get_page_number(request, paginator)

        try:
            # 尝试获取请求的页码
            self.page = paginator.page(page_number)
        except InvalidPage as exc:
            # 如果页码超出范围，返回空列表而不是错误
            self.page = self._empty_page()
            return []

        if paginator.num_pages > 1 and self.template is not None:
            # The browsable API should display pagination controls.
            self.display_page_controls = True

        self.request = request
        return list(self.page)

    def _empty_page(self):
        """创建一个空的分页对象"""
        paginator = Paginator([], self.page_size)
        return paginator.page(1)

    def get_paginated_response(self, data):
        """自定义分页响应格式"""
        return Response({
            'count': self.page.paginator.count,
            'total_pages': self.page.paginator.num_pages,
            'current_page': self.page.number,
            'page_size': self.page_size,
            'next': self.get_next_link(),
            'previous': self.get_previous_link(),
            'results': data
        })

